package app.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.Locale;

/**
 * 时间操作类，线程安全
 * 
 * @author xuxiaoyu@dejiplaza.com
 * @date 2021/3/19 13:40
 */
public class DateTimeUtils {

    /**
     * DateTimeFormatter yyyy-MM-dd HH:mm:ss
     */
    public final static DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss",
            Locale.US);

    /**
     * 更高精度的DateTimeFormatter yyyy-MM-dd HH:mm:ss.SSSSSSSSS
     */
    public final static DateTimeFormatter PRECISION_DATE_TIME_FORMATTER = DateTimeFormatter
            .ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSS", Locale.US);

    public static final String DEFAUL_TTIME_FORMAT = "yyy-MM-dd HH:mm:ss";

    public static SimpleDateFormat sdf = new SimpleDateFormat(DEFAUL_TTIME_FORMAT);

    private DateTimeUtils() {
    }

    /**
     * 将时间字符串转为时间戳
     *
     * @param timeString timeString yyyy-MM-dd HH:mm:ss格式
     * @return Long
     */
    public static Long formatTime2Timestamp(String timeString) {
        return parseLocalDateTime(timeString, DATE_TIME_FORMATTER).toInstant(ZoneOffset.of("+8")).toEpochMilli();
    }

    /**
     * 将时间字符串转为时间戳 兼容前端秒级别
     *
     * @param precisionTimeString timeString yyyy-MM-dd HH:mm:ss.SSSSSSSSS格式
     * @return Long
     */
    public static Long precisionFormatTime2Timestamp(String precisionTimeString) {
        return parseLocalDateTime(precisionTimeString, PRECISION_DATE_TIME_FORMATTER).toInstant(ZoneOffset.of("+8"))
                .toEpochMilli();
    }

    /**
     * 时间戳转为时间yyyy-MM-dd HH:mm:ss格式
     * 
     * @param timestamp 时间戳
     * @return 时间字符串
     */
    public static String timestamp2FormatTime(Long timestamp) {
        LocalDateTime epochMilliTime = LocalDateTime.ofInstant(Instant.ofEpochSecond(timestamp),
                ZoneId.systemDefault());
        return DATE_TIME_FORMATTER.format(epochMilliTime);
    }

    /**
     * 时间戳转为时间yyyy-MM-dd HH:mm:ss.SSSSSSSSS格式 兼容前端秒级别
     *
     * @param timestamp 时间戳
     * @return 时间字符串
     */
    public static String precisionTimestamp2FormatTime(Long timestamp) {
        LocalDateTime epochMilliTime = LocalDateTime.ofInstant(Instant.ofEpochSecond(timestamp),
                ZoneId.systemDefault());
        return PRECISION_DATE_TIME_FORMATTER.format(epochMilliTime);
    }

    /**
     * 格式化时间
     * 
     * @param timeString yyyy-MM-dd HH:mm:ss格式
     * @return 格式化后的时间
     */
    public static LocalDateTime parseLocalDateTime(String timeString, DateTimeFormatter dateTimeFormatter) {
        return LocalDateTime.parse(timeString, dateTimeFormatter);
    }

    /**
     * LocalDate转Date
     * 
     * @param localDate
     * @return
     */
    public static Date localDate2Date(LocalDate localDate) {
        if (null == localDate) {
            return null;
        }
        ZonedDateTime zonedDateTime = localDate.atStartOfDay(ZoneId.systemDefault());
        return Date.from(zonedDateTime.toInstant());
    }

    /**
     * 日期轉換成秒
     *
     * @param date
     * @return
     */
    public static Long parseDateToLong(Date date) {
        if (null != date) {
            return date.getTime() / 1000;
        }
        return null;
    }

    /**
     * 获取当前日期
     * 
     * @return
     */
    public static Date getCurrentDate() {
        return new Date();
    }

    /**
     * 将时间转成秒
     *
     * @param timeString
     * @return
     */
    public static Long formatTime2TimestampSeconds(String timeString) {
        return parseLocalDateTime(timeString, DATE_TIME_FORMATTER).toInstant(ZoneOffset.of("+8")).getEpochSecond();
    }

    /**
     * timeStr yyyy-MM-dd HH:mm:ss
     *
     * @param timeStr
     * @return
     */
    public static Date formatTimeStrToDate(String timeStr) {
        if (null == timeStr)
            return null;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DEFAUL_TTIME_FORMAT);
        try {
            return simpleDateFormat.parse(timeStr);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * @Description date转string
     **/
    public static String getStringByDate(Date date) {

        return date == null ? sdf.format(new Date()) : sdf.format(date);
    }

    /**
     * @Description Long转string
     **/
    public static String getStringByLong(Long time) {

        return time == null ? sdf.format(new Date()) : sdf.format(new Date(time * 1000));

    }

    /**
     * @Description 秒级时间戳转date类型
     **/
    public static Date getDateByLongTime(Long time) {
        return time == null ? new Date() : new Date(time * 1000);
    }

    /**
     * @Description date类型转秒级时间戳
     **/
    public static Long getLongByDateTime(Date time) {
        return time == null ? truncationThreePlace(System.currentTimeMillis()) : truncationThreePlace(time.getTime());
    }

    /**
     * @Description 截取Long时间戳后三位
     **/
    public static Long truncationThreePlace(Long time) {
        return time == null ? null : Long.parseLong(time.toString().substring(0, time.toString().length() - 3));
    }

    public static LocalDateTime precisionTimestampLocalDateTime(long timestamp) {
        return LocalDateTime.ofInstant(Instant.ofEpochSecond(timestamp), ZoneId.systemDefault());
    }
}
